package com.woniu.woniu_bx.mapper;

import cn.hutool.core.lang.copier.SrcToDestCopier;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.woniu.woniu_bx.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author : 王泰元
 * @description: 用户 mapper
 * @date : 2022/8/27 15:09
 */
@Repository
public interface UserMapper extends BaseMapper<User> {


    @Select("select user.avr,user.money from bx_user user where id = #{id}")
    User findByUserId(int id);


    /**
     * 得到关注列表，只查询 id、头像、昵称，其它详细信息可根据 id 再次查询
     *
     * @param id 用户id
     * @return 关注列表集合
     */
    @Select("select id, avr, nick, signature  " +
            "from bx_user, bx_like " +
            "where id = belike_id " +
            "and user_id = #{id} and eachCare='n'")
    List<User> getLikesById(Integer id);

    @Select("select id, avr, nick, signature  " +
            "from bx_user, bx_like " +
            "where id = belike_id " +
            "and user_id = #{id} and eachCare='y'")
    List<User> getLikesEachById(Integer id);

    //修改用户的基本个人信息昵称、生日、个性签名、头像
    @Update("update bx_user set nick=#{nick},birthday=#{birthday},signature=#{signature},avr=#{avr} where id = #{id}")
    void updateUserBaseInfo(User user);

    @Update("update bx_pw_img set img=#{img} where id = #{id}")
    void addPwImagesById(Integer id, String img);


    /**
     * 得到粉丝列表，只查询 id、头像、昵称，其它详细信息可根据 id 再次查询
     *
     * @param id 用户id
     * @return 粉丝列表集合
     */
    @Select("select id, avr, nick, signature  " +
            "from bx_user, bx_like " +
            "where id = user_id " +
            "and belike_id = #{id} and eachCare='n'")
    List<User> getFansById(Integer id);

    @Select("select id, avr, nick, signature  " +
            "from bx_user, bx_like " +
            "where id = user_id " +
            "and belike_id = #{id} and eachCare='y'")
    List<User> getFansEachById(Integer id);

    @Update("update bx_user set password=#{password} where id=#{id}")
    void updateUserPwd(@Param("id") Integer id, @Param("password") String password);

    /**
     * 动态更新用户信息，账户、性别、生日、注册时间不允许修改
     *
     * @param user 更新后的用户信息，将根据其中的id查找对应用户，然后更新其信息；若 user 中的 id 未赋初始值或不存在，将不会作任何修改
     */
    @UpdateProvider(type = UserSqlProvider.class, method = "update")
    void update(User user);

    @Select("select img from bx_pw_img where user_id = #{id}")
    List<String> getUserImagesById(Integer id);

    /**
     * 多条件查询用户信息
     *
     * @param user 封装了查询条件的 User 实例，如果为 null || user 中的属性未赋值，则将查询所有用户信息
     * @return 根据指定条件动态查询到的用户信息的 List 集合
     */
    @SelectProvider(type = UserSqlProvider.class, method = "select")
    @Results(id = "userMap", value = {
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "account", property = "account"),
            @Result(column = "avr", property = "avr"),
            @Result(column = "nick", property = "nick"),
            @Result(column = "gender", property = "gender"),
            @Result(column = "birthday", property = "birthday"),
            @Result(column = "reg_time", property = "regTime"),
            @Result(column = "auth_pw", property = "authPw"),
            @Result(column = "signature", property = "signature"),
            @Result(column = "status", property = "status"),
            @Result(column = "money", property = "money")
    })
    List<User> getByCondition(User user);

    @Insert("insert into bx_like values(#{myId},#{otherId},#{isEach})")
    void careSomebody(@Param("myId") Integer myId, @Param("otherId") Integer otherId, char isEach);

    @Delete("delete from bx_like where user_id=#{myId} and belike_id=#{otherId}")
    void cancelCare(@Param("myId") Integer myId, @Param("otherId") Integer otherId);

    @Insert("insert into bx_pw_img(user_id,img) values(#{userID},#{url})")
    void addUserImg(@Param("userID") Integer userID, @Param("url") String url);

    @Update("update bx_user set money = 0 where id=#{userId}")
    void withdrawPwMoney(@Param("userId") Integer userId);

    @Select("select count(*) from bx_like where user_id=#{id}")
    Integer getLikesCount(Integer id);

    @Select("select count(*) from bx_like where belike_id=#{id}")
    Integer getFansCount(Integer id);

    @Select("select * from bx_user where id=#{id}")
    User getUserById(Integer id);

    @Select("select sum(sale_num) from bx_goods where user_id = #{id}")
    Integer getUserTotalSaleNums(Integer id);

    @Select("select count(*) from bx_like where user_id=#{otherId} and belike_id=#{myId}")
    Integer findEach(Integer otherId, Integer myId);

    @Select("SELECT SUM(money) FROM bx_order WHERE user_id = #{uid}")
    BigDecimal getAllOrderMoneyByUid(@Param("uid") Integer uid);

    /**
     * 根据url删除图片
     *
     * @param img
     */
    @Delete("delete from bx_pw_img where img=#{img}")
    void deleteImage(String img);

    /**
     * 根据我的id和个人主页的id,判断我是否关注
     * @param myId
     * @param openUserId
     * @return
     */
    @Select("select count(*) from bx_like where user_id=#{myId} and belike_id=#{openUserId}")
    int careUser(@Param("myId") Integer myId,@Param("openUserId") Integer openUserId);

    @Update("update bx_like set eachCare=#{isEach} where user_id=#{otherId} and belike_id=#{myId}")
    void updateEach(@Param("otherId") Integer otherId, @Param("myId") Integer myId, @Param("isEach") char isEach);
    /* ***********************************/
    /*        sql 语句构建器               */
    /* ***********************************/

    /**
     * sql 语句构建器；
     * 根据传入的 user（封装了条件）、method，产生并返回对应的动态 sql 语句
     */
    @Slf4j
    class UserSqlProvider {
        /**
         * 得到动态修改的sql语句，账户、性别、生日、注册时间不允许修改
         *
         * @param user 封装了修改条件的 User 实例
         * @return 返回动态产生的sql语句
         */
        public String update(User user) {
            return new SQL() {
                {
                    UPDATE("bx_user");
                    if (StringUtils.hasLength(user.getPassword())) {
                        SET("password=#{password}");
                    }
                    if (StringUtils.hasLength(user.getAvr())) {
                        SET("avr=#{avr}");
                    }
                    if (StringUtils.hasLength(user.getNick())) {
                        SET("nick=#{nick}");
                    }
                    if (StringUtils.hasLength(user.getAuthPw())) {
                        SET("auth_pw=#{authPw}");
                    }
                    if (StringUtils.hasLength(user.getSignature())) {
                        SET("signature=#{signature}");
                    }
                    if (StringUtils.hasLength(user.getStatus())) {
                        SET("status=#{status}");
                    }
                    if (user.getMoney() != null) {
                        SET("money=#{money}");
                    }
                    WHERE("id=#{id}");
                }
            }.toString();
        }

        /**
         * 得到动态产生的多条件查询 sql 语句
         *
         * @param user 封装了查询条件的 Role 实例
         * @return 动态产生的 sql 查询语句
         */
        public String select(User user) {
            return new SQL() {
                {
                    SELECT("*").FROM("bx_user");
                    if (StringUtils.hasLength(user.getAccount())) {
                        WHERE("account like concat('%',#{account},'%')");
                    }
                    if (StringUtils.hasLength(user.getPassword())) {
                        WHERE("password=#{password}");
                    }
                    if (StringUtils.hasLength(user.getAvr())) {
                        WHERE("avr=#{avr}");
                    }
                    if (StringUtils.hasLength(user.getNick())) {
                        WHERE("nick=#{nick}");
                    }
                    if (StringUtils.hasLength(user.getGender())) {
                        WHERE("gender=#{gender}");
                    }
                    if (StringUtils.hasLength(user.getStartBirthday())) {
                        WHERE("birthday >= #{startBirthday}");
                    }
                    if (StringUtils.hasLength(user.getEndBirthday())) {
                        WHERE("birthday <= #{endBirthday}");
                    }
                    if (StringUtils.hasLength(user.getStartRegTime())) {
                        WHERE("reg_time >= #{startRegTime}");
                    }
                    if (StringUtils.hasLength(user.getEndRegTime())) {
                        WHERE("reg_time <= #{endRegTime}");
                    }
                    if (StringUtils.hasLength(user.getAuthPw())) {
                        WHERE("auth_pw=#{authPw}");
                    }
                    if (StringUtils.hasLength(user.getSignature())) {
                        WHERE("signature=#{signature}");
                    }
                    if (StringUtils.hasLength(user.getStatus())) {
                        WHERE("status=#{status}");
                    }
                }
            }.toString();
        }
    }
}
